﻿/**
 *		oss字符串处理
 */
#ifndef OSS_STRING_H_
#define OSS_STRING_H_
#include "ossType.h"
#include "ossSmartPtr.h"
#include "ossLock.h"
#include<stdarg.h>
#include <vector>
#include <string>


#pragma comment(lib,"legacy_stdio_definitions.lib")


    //空格字符的ASIIC码
#define SPACE_CHAR		32


/**
 *      判断是否为空格
 */
#define OssIsSpace(c)  (c == ' ')


/**
 *      GBK编码转UTF8编码
 *@lpGbkStr     带转换的gbk字符串
 *@lpUtf8Buff   存放结果的utf8缓存
 *@iBuffMax     lpUtf8Buff的最大容量
 *@return       成功返回utf8字符串的长度
 *              失败返回 0
 */
int OssGbk2Utf8(const char * lpGbkStr,int iGbkLen,char * lpUtf8Buff,int iBuffMax);

/**
 *      GBK编码转UNICODE
 *@lpGbkStr     带转换的gbk字符串
 *@lpUnicodeBuff   存放结果的utf8缓存
 *@iBuffMax     lpUnicodeBuff的最大容量
 *@return       成功返回Unicode字符串的长度
 *              失败返回 0
 */
int OssGbk2Unicode(const char * lpGbkStr,char * lpUnicodeBuff,int iBuffMax);

/**
 *      UTF8编码转GBK编码
 *@lpGbkStr     带转换的utf8字符串
 *@lpUtf8Buff   存放结果的gbk缓存
 *@iBuffMax     lpGbkBuff的最大容量
 *@return       成功返回GBK字符串的长度
 *              失败返回 0
 */
int OssUtf82Gbk(const char * lpUtf8Str,int iUtf8Len,char * lpGbkBuff,int iBuffMax);

/**
 *      UTF8编码转GBK编码
 *@lpGbkStr     带转换的utf8字符串
 *@iUtf8strMax	lpGbkStr的最大容量
 *@lpUtf8Buff   存放结果的gbk缓存
 *@iBuffMax     lpGbkBuff的最大容量
 *@return       成功返回GBK字符串的长度
 *              失败返回 0
 */
int OssUtf82GbkFullParam(char * lpUtf8Str,int iUtf8strMax,char * lpGbkBuff,int iGbkBuffMax);

/**
 *		utf8转Unicode
 */
int OssUtf82Unicode(const char* lpUtf8, WChar* lpUnicodeBuff, int iBuffMax);

/**
 *		unicode 转 utf8
 **/
int OssUnicode2Utf8(WChar* lpUnicodeStr,char* lpUtf8, int iBuffMax);


/**
 *		拷贝字符串，以\0结束
 */
char* OssStrcpy(char* dst,const char* src);

/**
 *		拷贝字符串，以\0结束
 */
char* OssStrncpy(char* dst,const char* src,int len);

/**
 *		拷贝显示字符串,包括空格
 */
char* OssStrncpyS(char* dst,char* src,int len);

/**
 *      将源串字符追加到到目的串上，追加后的长度不超过目标串最大缓
 */
char* OssStrncat( char *pcDst, int dwMaxSize, const char *pcSrc);

/**
 *		拷贝显示字符串，不包括空格
 */
char* OssStrncpyD(char* dst,const char* src,int len);

/**
 *		计算显示字符串的长度
 */
int OssStrlen(const char* str);

/**
 *		计算显示字符串的长度
 */
int OssStrlenD(char* str);

/**
 *		比较两个字符串，以\0结束
 */
int OssStrcmp(const char* str1,const char* str2);

/**
 *		比较前n个字符
 */
int OssStrncmp(const char* str1,const char* str2,int n);

/**
 *		比较两个字符串忽略大小写
 */
int OssStricmp(char* str1,char* str2);

/**
 *     比较前n个字符 
 */
int OssStrnicmp(const char* str1,const char* str2,int n);

/** 
*       忽略大小写比较可见字符串
*@return    可见字符串相同则返回0
*           否则返回非0
 */
int OssStricmpD(const char* str1,const char* str2);

/**
 *		比较显示字符串
 *	将空格看成是不可见字符,以空格或小于空格的字符为结束符
 */
int OssStrcmpD(const char* str1,const char* str2);

/**
 *		比较拉丁字母和数字，区分大小写
 * 将非abc字母和数字认为结束符
 */
int OssStrcmpLatin(const char* str1,const char* str2);

/**
 *		以后一个字符串的长度比较
 */
int OssStrcmpBehind(const char* str1,const char*str2);

/**
 *		找字符的位置
 *@return	成功返回找到的位置
 *			失败返回-1
 */
int OssStrFindChar(const char* str,char findchar);

/**
 *		查找字符串string中首次出现字符ch的位置。如果string中存在字符ch，返回首次出现ch的位置的指针；否则返回NULL。
 */
char* OssStrchr(const char *str, int c);

/**
 *		从后往前查第一个字符
 */
char* OssStrrchr(const char *str, int c);

/**
 *		找子串
 */
char* OssStrstr(const char *buf, const char *sub);

/**
 *		找子串,指定结束位置
 *@notes  
 */
char* OssStrstrSE(const char *buf, const char *sub,const char* pcEnd);

/**
 *      逆向查找字符串
 */
const char* OssReverseFind(const char* pcSrc,const char* pcTag);

//在源字符串（s1）中找出最先含有搜索字符串（s2）中任一字符的位置并返回，若找不到则返回空指针。
char* OssStrpbrk(const char * cs,const char * ct);


char* OssStrReplace(char* str1,char old,char ne);

/**
 *		替换--还未实现
 */
char* OssStrReplace1(char* str1, int strBufMax, const char* subStr, const char* str);

/**
 *      略过 n 个字符串
 *      字符以空格分隔，略过前面n个分隔的字符串
 *@return   成功返回略过后的字符串开始地址
 *          失败返回NULL
 */
char* OssSkipNString(unsigned char* str,int nLen,int n);

/*
   http://blog.csdn.net/ammana_babi/article/details/1414045
   将字符串转换为大写。只改变字符串中出现的小写字母，不改变其他字符。
*/
char * OssStrupr(char *str);

DWord OssMakeStrUpperCase(const char * szScr, char  * szDstBuf);

/*
   将字符串转换为小写。只改变字符串中出现的大写字母，不改变其他字符。
*/
char* OssStrlwr(char *str);

/*
	http://blog.csdn.net/ammana_babi/article/details/1414133
   把字符串的所有字符的顺序颠倒过来（不包括空字符NULL）。
   返回指向颠倒顺序后的字符串指针。
*/
char* OssStrrev(char* str);

//判断字符c是否为空白符。空白符指空格、水平制表、垂直制表、换页、回车和换行符。
//若参数c为空格字符，则返回TRUE，否则返回NULL(0)。
int OssIsspace( int ch );

//判断字符c是否为数字
int OssIsdigit( int ch );

//判断字符c是否为英文字符
int OssIsalpha( int ch);

//判断字符c是否为大写英文字母
int OssIsupper( int ch );

//判断字符c是否为16进制的字母
int OssIsxdigit(int ch);

/*
 *		将字符串转换成长整型
 *@nptr		需要转换的字符串
 *@endptr	保存末尾指针
 *@base		基数，
 *				0:	使用默认的基数，默认为10进制，可自动识别8进制和16进制
 *				2:  二进制
 *				8:  八进制
 *				10:	十进制
 *				16: 十六进制
 *@return	返回转换结果
*/
int OssStrtol(const char *nptr, char **endptr, int base);

/**
 *		将字符串转换成整型
 */
int OssAtoi(const char *nptr);

/**
 *      将数字转换为
 */
//int OssItoa(int iVal,char* buf,int bufMax,int Radix);

/**
 *		将字符串转换为double类型
 *@str		待转换的字符串
 *@endPos	转换后结束的字符位置，如果传NULL，则忽略
 *@return	返回转换得到的数值
 */
double OssStrtoD(const char* IN str,char**	OUT endPos);

/**
 *		将可变个参数(...)按照format格式化成字符串，然后将其复制到str中
 */
int OssSnprintf(char *str, int iMaxSize, const char *format, ...);
int OssSnprintfV(char *str, int iMaxSize, const char *format,va_list a_args);

/**
 *		将可变个参数(...)按照format格式化成字符串，然后将其复制到str中
 */
int OssSprintf(char *str, const char *format, ...);
int OssSprintfV(char *str, const char *format, va_list a_args);

/**
*		忽略不可见字符
*	将空格看成是不可见字符
*/
char* OssSkipToD(const char* str);

/**
 *		忽略可见字符
 */
char* OssSkipD(const char* str);

/**
*		回退到可见字符
*@pcStart       起始字符，回退时不能超出本地址
*/
char* OssBackToD(const char* str,const char* pcStart);

/**
*		回退忽略可见字符
*@pcStart       起始字符，回退时不能超出本地址
*/
char* OssBackSkipD(const char* str, const char* pcStart);

/**
 *      忽略指定的字符
 */
char* OssSkipChar(const char* str, const char cSkip);

/**
 *      调到指定的字符
 * @return		如果str中没有指定的cTo字符，则返回第一个位置
 *				如果str中没有指定的cTo字符，则返回str的结束位置
 */
char* OssSkipToChar(const char* str, const char cTo);


/**
 *		生成session(随机字符串 )
 */
void OssGenerateSession(char* session,int nLen);

/**
 *		将两个字节的hex字符串转换成一个字符，例如"30" --> '0',0x30 = '0'
 *@hex		需要转换的hex字符串，只用两位
 *@return	返回转换的字符
 */
char OssHex2Char(char* hex);

/**
 *		向指定的内存填充数字
 *@buff			填充的目的内存
 *@fillWord		填充的数字
 *@return		返回填充的字节数
 *@notes		以大字节序的方式填充
 *@date			2015年12月9日
 */
int OssFillDword(Byte* buff,DWord fillWord);

/**
 *		将16进制数转换为字符串
 *@abyHex		待转换的16进制数据
 *@iHexLen		待转换的数据长度
 *@strBuf		接收字符串的缓冲区
 *@iStrMax		缓冲区大小
 *@return		返回strBuf所用的大小
 *				失败返回 0 
 */
int OssHexToStr(Byte* abyHex,int iHexLen,char* strBuf,int iStrMax);

/**
 *		将16进制字符串转换为16进制数
 *@return		成功返回转换后的字符个数
 */
int OssStrToHex(char* szHex,Byte *abyHexBuf,DWord dwBufMax);

/**
 *		将bcd编码字符串转换为数据
 *@bdcStr		bcd编码的字符串
 *@pbyData		OUT 数据的缓存
 *@iBufMax		缓存最大容量
 *@return		转换后的字节长度
 */
int OssBcdStrToData(char* bdcStr,Byte *pbyBcd,int iBufMax);

/**
 *		将数据转换为BCD编码字符串
 *@pbyData		待转换的数据
 *@iDataLen		指定pbyData的大小
 *@bcdStrBuf		OUT 接收转换后的字符串缓冲区
 *@iStrBufMax		指定缓冲区的大小,iStrBufMax必须大于等于iDataLen*2 + 1，最后一位存'\0'
 *@return		返回bcd字符串的长度
 */
Bool OssDataToBcdStr(Byte *pbyData,int iDataLen,char* bcdStrBuf,int iStrBufMax);

/**
 *		提取引号中的字符串，以" 或者' 开头
 *@return		返回消耗pcSrc的字符个数
 */
int OssPickString(const char* pcSrc,char* pcPicked,int iMax);

/**
 *		将指定的字符串拆分
 *@str		需要被拆分的字符串
 *@delim	拆分字符
 */
std::vector<std::string> OssStringSplit(const std::string& str, const char delim);



//////////////////////////////////////////////////////////////////////////
//c++
//摘抄自：http://blog.csdn.net/jones2000/article/details/984578
//2014年6月28日
#ifdef __cplusplus	

//记录字符串基本信息的结构体，
//分配内存空间时多分配sizeof(OssStringData)的长度，
//前面为OssStringData的信息，后面为实际字符串的空间
class OssStringData
{
public:
	OssStringData();
	OssStringData(int allocLen);
	OssStringData(OssStringData& strData);
	OssStringData(OssStringData& strData,int allocLen);//拷贝原有数据，并分配内存
	~OssStringData();

	char*		mydata;
	int			nDataLength;	//字符使用长度
	int			nAllocLength;	//分配长度
	OssMutex	    lock;
};

class OssString 
{
public:
	//构造函数
	OssString();
	OssString(const OssString& stringSrc);
	OssString(char ch, int nLength =1);
	OssString(const char* lpsz); 
	OssString(char* lpch, int nLength); 
	OssString(const unsigned char* psz);
	virtual ~OssString();

	//CStringData的属性
	int GetLength() const;		//得到字符长度
	int GetAllocLength() const; //得到分配的内存长度
	Bool IsEmpty() const;		//判断字符长度是否为0
	operator char*() const;	//类型转换
	void Empty();				//清空CStringData

	//操作符重载
	const OssString& operator=(const OssString& stringSrc);
	const OssString& operator=(char* lpsz);
	const OssString& operator=(char ch);
	const OssString& operator+=(const OssString& string);
	const OssString& operator+=(char ch);
	const OssString& operator+=(char* lpsz);
	char operator[](int nIndex) const;

	friend OssString operator+(const OssString& string1,const OssString& string2);
	friend OssString operator+(const OssString& string, char ch);
	friend OssString operator+(char ch, const OssString& string);
	friend OssString operator+(const OssString& string, char* lpsz);
	friend OssString operator+(char* lpsz, const OssString& string);

	//操作,脱离共享数据块
	int Delete(int nIndex, int nCount = 1);			//删除从nIndex开始长度为nCount的数据
	int Insert(int nIndex, char ch);				//插入一个字符
	int Insert(int nIndex, char* pstr);			//插入一个字符串
	int Replace(const char* lpszOld,const char* lpszNew);	//替换数据
	int Replace(char chOld, char chNew);			//替换数据
	int Remove(char chRemove);						//移除一个字符
	void TrimRight(char* lpszTargetList);
	void TrimRight(char chTarget);					//去掉右边chTarget
	void TrimRight();								//去掉右边空格
	void TrimLeft(char* lpszTargets);
	void TrimLeft(char chTarget);					//去掉左边chTarget
	void TrimLeft();								//去掉左边空格
	void Trim();


	//取某段字符串
	void SetAt(int nIndex, char ch);
	char GetAt(int nIndex) const;
	OssString Mid(int nFirst) const;				//取某段字符串
	OssString Mid(int nFirst, int nCount) const;	//取某段字符串
	OssString Right(int nCount) const;				//取右边字符串
	OssString Left(int nCount) const;				//取左边字符串

	void MakeUpper();	//大写
	void MakeLower();	//小写
	void MakeReverse();	//发转字符串

	//查找
	int Find(char ch) const;
	int Find(char ch, int nStart) const;
	int ReverseFind(char ch) const;
	int Find(char* lpszSub) const;
	int Find(char* lpszSub, int nStart) const;
	int FindOneOf(char* lpszCharSet) const;	//得到第一个匹配lpszCharSet中其中一个字符的位置 调用_tcspbrk

	//高级操作
	const char* GetString() const;
	char* GetBuffer(int nMinBufLength);		//重新分配内存,在拷贝原来的数据
	void  SetDataLen(int dataLen);			//设置使用的内存大小，该操作要慎重，否则会影响字符串的性质
	void ReleaseBuffer(int nNewLength=-1);		//在[nNewLength]='/0',对内存大小没有改变
	char* GetBufferSetLength(int nNewLength);	//重新分配内存,在拷贝原来的数据
	void FreeExtra();							//深拷贝自己,然后--原来的引用记数器

	//比较
	int Compare(char* lpsz) const;		//区分大小写比较
	int CompareNoCase(char* lpsz) const;	//不区分大小写比较

	//格式化字符串
	void Format(const char* lpszFormat, ...);	//

	/**
	 *		追加格式化字符串
	 */
	int AppendFormat(const char* lpszFormat, ...);

private:
	void Init();
	void AllocBuffer(int nLen);			//给OssStringData分配内存,不带记数器
	void CopyBeforeWrite();				//带引用记数的复制自己深拷贝
	void AllocBeforeWrite(int nLen);	//给OssStringData分配内存,带记数器
	void AssignCopy(int nSrcLen, char* lpszSrcData);//分配内存,并拷贝lpszSrcData内容

	//把nCopyIndex开始的nCopyLen长度的数据拷贝给dest,nExtraLen扩充的长度,次函数好像没下面用
	void AllocCopy(OssString& dest, int nCopyLen, int nCopyIndex,int nExtraLen) const;
	void Release();											//--引用记数器并判断是否删除内存,如删除并初始化
	void FormatV(const char* lpszFormat, va_list argList);		//格式化字符串
	void ConcatCopy(int nSrc1Len, char* lpszSrc1Data,
		int nSrc2Len, char* lpszSrc2Data);				//连接数据lpszSrc1Data+lpszSrc2Data
	void ConcatInPlace(int nSrcLen, char* lpszSrcData);	//连接字符串

	static int SafeStrlen(const char* lpsz);		//得到长度

	OssSmartPtr<OssStringData>	m_strdata;
};

/*调用CString::Compare比较大小,如果比较中有CStirng的话用
调用operator char*()转化类型为char*
*/
bool operator==(const OssString& s1, const OssString& s2);
bool operator==(const OssString& s1, char* s2);
bool operator==(char* s1, const OssString& s2);
bool operator!=(const OssString& s1, const OssString& s2);
bool operator!=(const OssString& s1, char* s2);
bool operator!=(char* s1, const OssString& s2);
bool operator<(const OssString& s1, const OssString& s2);
bool operator<(const OssString& s1, char* s2);
bool operator<(char* s1, const OssString& s2);
bool operator>(const OssString& s1, const OssString& s2);
bool operator>(const OssString& s1, char* s2);
bool operator>(char* s1, const OssString& s2);
bool operator<=(const OssString& s1, const OssString& s2);
bool operator<=(const OssString& s1, char* s2);
bool operator<=(char* s1, const OssString& s2);
bool operator>=(const OssString& s1, const OssString& s2);
bool operator>=(const OssString& s1, char* s2);
bool operator>=(char* s1, const OssString& s2);

#endif	
#endif
